package net.longjin.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.houbb.heaven.util.lang.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:AOP拦截打印请求地址、参数
 * @Author 何志鹏
 * @Date 2020/6/1 14:30
 * @Version 1.0
 */
@Aspect
@Component
@Slf4j
public class ConsoleLogAspect {


    //设置切面点
    @Pointcut(value = "(execution(* net.longjin.controller.*.*(..))))")
    public void webLog() {
    }

    //指定切点前的处理方法
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint)  {
        try {
            //获取request对象
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            StringBuilder sb = new StringBuilder();
            //拼接请求内容
            sb.append("\n请求路径:").append(request.getRequestURL().toString()).append("  ").append(request.getMethod()).append("\n");
            sb.append("\n请求Token:").append(request.getHeader("token")).append("\n");
            //判断请求是什么请求
            if (request.getMethod().equalsIgnoreCase(RequestMethod.GET.name())) {
                Map<String, String[]> parameterMap = request.getParameterMap();
                Map<String, String> paramMap = new HashMap<>();
                parameterMap.forEach((key, value) -> paramMap.put(key, String.join(",", value)));
                sb.append("请求参数:").append(JSON.toJSONString(paramMap));
            } else if (request.getMethod().equalsIgnoreCase(RequestMethod.POST.name())) {
                Object[] args = joinPoint.getArgs();
                StringBuilder stringBuilder = new StringBuilder();
                if(ObjectUtil.isNotEmpty(args)){
                    for (Object o : args) {
                        //只取自定义的参数, 自带的HttpServletRequest, HttpServletResponse不管
                        if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) {
                            continue;
                        }
                        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(o));
                        if(null != jsonObject){
                            stringBuilder.append(jsonObject.toString().replace("=", ":"));
                        }
                    }
                }
                if (stringBuilder.length() == 0) {
                    stringBuilder.append("{}");
                }
                sb.append("请求参数:").append(stringBuilder.toString());
            }
            log.info(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //指定切点前的处理方法
    @AfterReturning(pointcut = "webLog()", returning = "result")
    public void doAfterReturning(Object result) {
        if (ObjectUtils.isEmpty(result)) {
            return;
        }
        String resultStr = JSON.toJSONString(result);
        JSONObject jsonObject = JSONObject.parseObject(resultStr);
        String code = jsonObject.getString("code");
        String message = jsonObject.getString("message");
        String result1 = jsonObject.getString("result");
        log.info("\n返回结果:" + "code:" + code + "," + "message:" + message+","+"result："+result1);
    }

}
